/*  
 * @(#) ImageHelper.java Create on 2014-3-19 下午01:36:42   
 *   
 * Copyright 2014 by fibrlink.   
 */


package com.springdemo.tools;

import com.springdemo.basic.common.ErrorFlag;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;

/**
 * 
 * @author san
 * @date   2014-3-19
 */
public class ImageHelper {
	
	
private ImageHelper(){}
	
	private BufferedImage image = null;

	public void load(File imageFile) throws IOException {
		image = ImageIO.read(imageFile);
	}

	public int getImageWidth() {
		return image.getWidth();
	}

	public int getImageHeight() {
		return image.getHeight();
	}

	//图片裁剪
	public void cutTo(int x,int  y,int tarWidth, int tarHeight) throws FileNotFoundException {
		if (image == null) {
			throw new FileNotFoundException(
					"image file not be load.please execute 'load' function agin.");
		}
		int iSrcWidth = getImageWidth(); // 得到源图宽
		int iSrcHeight = getImageHeight(); // 得到源图长

		// 如果源图片的宽度或高度小于目标图片的宽度或高度，则直接返回出错
		if (iSrcWidth < tarWidth || iSrcHeight < tarHeight) {
			
			throw new RuntimeException("source image size too small.");
		}

		// 先求源图和目标图的尺寸比例
		double dSrcScale = iSrcWidth * 1.0 / iSrcHeight;
		double dDstScale = tarWidth * 1.0 / tarHeight;

		// 先确定剪裁尺寸
		int iDstWidth, iDstHeight;
		if (dDstScale > dSrcScale) { // 目标图片宽
			iDstWidth = iSrcWidth;
			iDstHeight = (int) (iDstWidth * 1.0 / dDstScale);
		} else { // 目标图片高
			iDstHeight = iSrcHeight;
			iDstWidth = (int) (iDstHeight * dDstScale);
		}
//		iDstLeft = (iSrcWidth - iDstWidth) / 2;
//		iDstTop = (iSrcHeight - iDstHeight) / 2;

		// 剪裁
		this.image = image.getSubimage(x, y, tarWidth, tarHeight);

	}

	
	
	/**
	 * 	//图片缩放 不生成新的图片
	 */
	public void zoomTo(int tarWidth, int tarHeight) {
		BufferedImage tagImage = new BufferedImage(tarWidth, tarHeight,
				BufferedImage.TYPE_INT_RGB); // 缩放图像
		Image image = this.image.getScaledInstance(tarWidth, tarHeight,
				Image.SCALE_SMOOTH);
		Graphics g = tagImage.getGraphics();
		g.drawImage(image, 0, 0, null); // 绘制目标图
		g.dispose();
		this.image = tagImage;

	}

	/**
	 * 保存
	 * @param fileName
	 * @param formatName
	 * @throws IOException
	 */
	public void save(String fileName, String formatName) throws IOException {
		// 写文件
		FileOutputStream out = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ImageIO.write(this.image, formatName, bos);// 输出到bos
			out = new FileOutputStream(fileName);
			out.write(bos.toByteArray()); // 写文件
		} catch (IOException e) {
			throw e;
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	
	/**
	 * //缩放图片 生成新的图片
	 */
	public static boolean zoomImage(String srcFile, String dstFile, int width,
			int height, String formatName) {
		try {
			ImageHelper zoom = new ImageHelper();
			zoom.load(new File(srcFile));
			zoom.zoomTo(width, height);
			zoom.save(dstFile, formatName);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		return true;
	}

	private static ImageHelper fromImageFile(File file) throws IOException {
		ImageHelper utils = new ImageHelper();
		utils.load(file);
		return utils;
	}

	/**
	 * 加载图片
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static ImageHelper load(String fileName) throws IOException {
		File file = new File(fileName);
		return fromImageFile(file);
	}
	
	

	
		/**
		 * 生成缩小图
		 * @Title: makeSmallImage
		 * @data:2014-4-24上午11:15:15
		 * @author:san
		 *
		 * @param srcImageFile
		 * @param dstImageFileName
		 * @throws Exception
		 */
	  public static void makeSmallImage(File srcImageFile,String dstImageFileName) throws Exception {
	    	
			File smallfile= new File(dstImageFileName);
	        FileOutputStream fileOutputStream = null;
	        JPEGImageEncoder encoder = null;
	        BufferedImage tagImage = null;
	        Image srcImage = null;
	        try{
	            srcImage = ImageIO.read(srcImageFile);
	            int srcWidth = srcImage.getWidth(null);//原图片宽度
	            int srcHeight = srcImage.getHeight(null);//原图片高度
	            int dstMaxSize = 300;//目标缩略图的最大宽度/高度，宽度与高度将按比例缩写
	            int dstWidth = srcWidth;//缩略图宽度
	            int dstHeight = srcHeight;//缩略图高度
	            float scale = 0;
	    		if (!smallfile.exists()) {
	    			File parentFile = smallfile.getParentFile();
	    			if (!parentFile.exists()){
	    				parentFile.mkdirs();
	    				smallfile.createNewFile();
	    			}
	    		}
	            //计算缩略图的宽和高
	            if(srcWidth>dstMaxSize){
	                dstWidth = dstMaxSize;
	                scale = (float)srcWidth/(float)dstMaxSize;
	                dstHeight = Math.round((float)srcHeight/scale);
	            }
	            srcHeight = dstHeight;
	            if(srcHeight>dstMaxSize){
	                dstHeight = dstMaxSize;
	                scale = (float)srcHeight/(float)dstMaxSize;
	                dstWidth = Math.round((float)dstWidth/scale);
	            }
	            //生成缩略图
	            tagImage = new BufferedImage(dstWidth,dstHeight,BufferedImage.TYPE_INT_RGB);
	            tagImage.getGraphics().drawImage(srcImage,0,0,dstWidth,dstHeight,null);
	            fileOutputStream = new FileOutputStream(dstImageFileName);
	            encoder = JPEGCodec.createJPEGEncoder(fileOutputStream);
	            encoder.encode(tagImage);
	            fileOutputStream.close();
	            fileOutputStream = null;
	        }finally{
	            if(fileOutputStream!=null){
	                try{
	                    fileOutputStream.close();
	                }catch(Exception e){
	                }
	                fileOutputStream = null;
	            }
	            encoder = null;
	            tagImage = null;
	            srcImage = null;
	            System.gc();
	        }
	    }
	  
		/**
		 * 宽度不一定的缩小图
		 * @Title: makeSmallImage
		 * @data:2014-4-24上午11:15:15
		 * @author:san
		 *
		 * @param srcImageFile
		 * @param dstImageFileName
		 * @throws Exception
		 */
	  public static void makeHomeSmallImage(File srcImageFile,String dstImageFileName,int maxWidth) throws Exception {
	    	
			File smallfile= new File(dstImageFileName);
	        FileOutputStream fileOutputStream = null;
	        JPEGImageEncoder encoder = null;
	        BufferedImage tagImage = null;
	        Image srcImage = null;
	        try{
	            srcImage = ImageIO.read(srcImageFile);
	            int srcWidth = srcImage.getWidth(null);//原图片宽度
	            int srcHeight = srcImage.getHeight(null);//原图片高度
	            int dstMaxSize = maxWidth;//目标缩略图的最大宽度/高度，宽度与高度将按比例缩写
	            int dstWidth = srcWidth;//缩略图宽度
	            int dstHeight = srcHeight;//缩略图高度
	            float scale = 0;
	    		if (!smallfile.exists()) {
	    			File parentFile = smallfile.getParentFile();
	    			if (!parentFile.exists()){
	    				parentFile.mkdirs();
	    				smallfile.createNewFile();
	    			}
	    		}
	            //计算缩略图的宽和高
	            if(srcWidth>dstMaxSize){
	                dstWidth = dstMaxSize;
	                scale = (float)srcWidth/(float)dstMaxSize;
	                dstHeight = Math.round((float)srcHeight/scale);
	            }
	            srcHeight = dstHeight;
	            if(srcHeight>dstMaxSize){
	                dstHeight = dstMaxSize;
	                scale = (float)srcHeight/(float)dstMaxSize;
	                dstWidth = Math.round((float)dstWidth/scale);
	            }
	            //生成缩略图
	            tagImage = new BufferedImage(dstWidth,dstHeight,BufferedImage.TYPE_INT_RGB);
	            tagImage.getGraphics().drawImage(srcImage,0,0,dstWidth,dstHeight,null);
	            fileOutputStream = new FileOutputStream(dstImageFileName);
	            encoder = JPEGCodec.createJPEGEncoder(fileOutputStream);
	            encoder.encode(tagImage);
	            fileOutputStream.close();
	            fileOutputStream = null;
	        }finally{
	            if(fileOutputStream!=null){
	                try{
	                    fileOutputStream.close();
	                }catch(Exception e){
	                }
	                fileOutputStream = null;
	            }
	            encoder = null;
	            tagImage = null;
	            srcImage = null;
	            System.gc();
	        }
	    }


    public static double getScaling(double targetWidth, double targetHeight, double standardWidth, double standardHeight) {
        double widthScaling = 0d;
        double heightScaling = 0d;
        if (targetWidth > standardWidth) {
            widthScaling = standardWidth / (targetWidth * 1.00d);
        } else {
            widthScaling = 1d;
        }
        if (targetHeight > standardHeight) {
            heightScaling = standardHeight / (targetHeight * 1.00d);
        } else {
            heightScaling = 1d;
        }
        return Math.min(widthScaling, heightScaling);
    }


    /**
     * 强制压缩图片大小
     * @param tarWidth
     * @param tarHeight
     */
    public void reSize(int srcw,int srcH,int tarWidth, int tarHeight,String srcPath)  {
        FileOutputStream out = null;
        double scaling = getScaling(srcw, srcH, tarWidth, tarHeight);
        tarWidth =(int)Math.round(srcw * scaling);
        tarHeight =(int)Math.round(srcH * scaling);
        BufferedImage tagImage = new BufferedImage(tarWidth, tarHeight,
                BufferedImage.TYPE_INT_RGB); // 缩放图像
        try {
            Image   srcImage = ImageIO.read(new File(srcPath));
            tagImage.getGraphics().drawImage(srcImage, 0, 0, tarWidth, tarHeight, null);
            //输出到文件流
            out = new FileOutputStream(srcPath);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(tagImage);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
	  


	/**
	 * 检查图片格式
	 * @Title: checkImageFile
	 * @data:2016-5-1下午3:51:58
	 * @author:charlin_yin
	 *
	 * @param file
	 * @param fileName
	 * @param imgSize
	 * @return
	 * @throws Exception
	 */
	private static int checkImageFile(File file, String fileName, String imgSize) throws Exception {
		int returnParam = 1;
		if (file != null && fileName != null && fileName.length() > 0) {
			FileInputStream fis = new FileInputStream(file);
			// 文件
			long size = Long.parseLong(String.valueOf(fis.available()));
			// 读取上传文件内容
			String[] imgTypes = new String[] { "gif", "jpg", "jpeg", "png", "bmp" };
			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
			String name = fileName.substring(0,	fileName.lastIndexOf("."));//不带后缀的文件名
			// 上传类型不对
			if (!Arrays.<String> asList(imgTypes).contains(fileExt)) {
				returnParam = ErrorFlag.TYPE_ERROR;
				return returnParam;
			}
			// 文件过大
			if (size > NumberHelper.stringToInt(imgSize)) {
				returnParam = ErrorFlag.FILE_SIZE_ERROR;
				return returnParam;
			}
			// 文件名不能包含“.”
			if(name.contains(".")){
				returnParam = ErrorFlag.FILE_NAME_ERROR;
				return returnParam;
			}
		}
		return returnParam;
	}


}
